//! # Kind
//!
//! 定义卡牌的类型

/// 卡牌类型
///
/// 主类型：基本牌、锦囊牌、装备牌，其他为副类别，其中坐骑还有细分
///
#[derive(Debug, Clone, PartialEq)]
pub enum Kind {
    /// 未知类型，一般表示出错
    Unknown,

    /// 基本牌 主类别
    Basic,

    /// 锦囊牌 主类别
    SilkBag,

    /// 非延时锦囊牌 副类别
    NonDelaySilkBag,

    /// 延时锦囊牌 副类别
    DelaySilkBag,

    /// 装备牌 主类别
    Equipment,

    /// 武器牌 副类别
    Weapon,

    /// 防具牌 副类别
    Armor,

    /// 坐骑牌 副类别
    Horse,

    /// 进攻坐骑牌 再细分副类别
    AttackHorse,

    /// 防御坐骑牌 再细分副类别
    DefendHorse,

    /// 宝物牌 主类别
    Treasure,
}

impl Default for Kind {
    fn default() -> Self {
        Self::Unknown
    }
}

impl TryFrom<&str> for Kind {
    type Error = crate::ParseStrError;

    fn try_from(text: &str) -> Result<Self, Self::Error> {
        match text {
            "基本" | "基本牌" | "Basic" | "BASIC" => Ok(Self::Basic),

            "锦囊" | "锦囊牌" | "SilkBag" => Ok(Self::SilkBag),

            "延时" | "延时锦囊" | "延时锦囊牌" | "DelaySilkBag" => {
                Ok(Self::DelaySilkBag)
            }

            "非延" | "非延时" | "非延时锦囊" | "非延时锦囊牌" | "NonDelaySilkBag" => {
                Ok(Self::NonDelaySilkBag)
            }

            "装备" | "装备牌" | "Equipment" => Ok(Self::Equipment),

            "武器" | "武器牌" | "Weapon" | "WeaponEquipment" => Ok(Self::Weapon),

            "防具" | "防具牌" | "Armor" | "ArmorEquipment" => Ok(Self::Armor),

            "马" | "坐骑" | "坐骑牌" | "Horse" | "HorseEquipment" => Ok(Self::Horse),

            "进攻马" | "-1马" | "-1" | "Attack" | "AttackHorse" => Ok(Self::AttackHorse),

            "防御马" | "+1马" | "+1" | "Defend" | "DefendHorse" => Ok(Self::DefendHorse),

            "宝物" | "宝物牌" | "Treasure" => Ok(Self::Treasure),

            _ => Err(crate::ParseStrError::new(crate::ParseType::Kind, text)),
        }
    }
}

impl Kind {
    /// 判断是否是主类别
    ///
    /// 即 `Kind::Basic` | `Kind::SilkBag` | `Kind::Equipment` | `Kind::Treasure`
    pub fn is_main(&self) -> bool {
        match self {
            Self::Basic | Self::SilkBag | Self::Equipment | Self::Treasure => true,
            _ => false,
        }
    }

    /// 获取父级类别，如果是主类别则返回自身
    ///
    /// 对于 `Self::AttackHorse` | `Self::DefendHorse` 返回结果并非主类别
    pub fn to_super(&self) -> Self {
        match self {
            Self::Basic | Self::SilkBag | Self::Equipment | Self::Treasure => self.to_owned(),
            Self::DelaySilkBag | Self::NonDelaySilkBag => Self::SilkBag,
            Self::Armor | Self::Weapon | Self::Horse => Self::Equipment,
            Self::AttackHorse | Self::DefendHorse => Self::Horse,
            _ => Self::Unknown,
        }
    }

    /// 获取主类别，如果是主类别则返回自身
    pub fn to_main(&self) -> Self {
        self.to_super().to_super()
    }
}

impl std::fmt::Display for Kind {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "{}",
            match self {
                Kind::Unknown => "Unknown",
                Kind::Basic => "基本",
                Kind::SilkBag => "锦囊",
                Kind::NonDelaySilkBag => "非延时锦囊",
                Kind::DelaySilkBag => "延时锦囊",
                Kind::Equipment => "装备",
                Kind::Weapon => "武器",
                Kind::Armor => "防具",
                Kind::Horse => "坐骑",
                Kind::AttackHorse => "进攻马",
                Kind::DefendHorse => "防御马",
                Kind::Treasure => "宝物",
            }
        )
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn test_try_from_str() {
        assert_eq!(Kind::try_from("基本牌").unwrap(), Kind::Basic);
        assert!(Kind::try_from("???").is_err())
    }
}
